home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / glibc-1.09 / glibc-1 / glibc-1.09.1 / sysdeps / unix / bsd / sun / m68k / sigtramp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-18  |  3.5 KB  |  143 lines

  1. /* Copyright (C) 1993 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3.  
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of the
  7. License, or (at your option) any later version.
  8.  
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with the GNU C Library; see the file COPYING.LIB.  If
  16. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  17. Cambridge, MA 02139, USA.  */
  18.  
  19. #include <ansidecl.h>
  20.  
  21. #ifndef    __GNUC__
  22.   #error This file uses GNU C extensions; you must compile with GCC.
  23. #endif
  24.  
  25. /* Get the definition of `struct sigcontext'.  */
  26. #define    KERNEL
  27. #define    sigvec        sun_sigvec
  28. #define    sigstack    sun_sigstack
  29. #define    sigcontext    sun_sigcontext
  30. #include "/usr/include/sys/signal.h"
  31. #undef    sigvec
  32. #undef    sigstack
  33. #undef    sigcontext
  34. #undef    NSIG
  35. #undef    SIGABRT
  36. #undef    SIGCLD
  37. #undef    SV_ONSTACK
  38. #undef    SV_RESETHAND
  39. #undef    SV_INTERRUPT
  40. #undef    SA_ONSTACK
  41. #undef    SA_NOCLDSTOP
  42. #undef    SIG_ERR
  43. #undef    SIG_DFL
  44. #undef    SIG_IGN
  45. #undef    sigmask
  46. #undef    SIG_BLOCK
  47. #undef    SIG_UNBLOCK
  48. #undef    SIG_SETMASK
  49.  
  50. #include <signal.h>
  51. #include <stddef.h>
  52. #include <errno.h>
  53.  
  54. /* Defined in __sigvec.S.  */
  55. extern int EXFUN(__raw_sigvec, (int sig, CONST struct sigvec *vec,
  56.                 struct sigvec *ovec));
  57.  
  58. /* User-specified signal handlers.  */
  59. #define mytramp 1
  60. #ifdef mytramp
  61. static __sighandler_t handlers[NSIG];
  62. #else
  63. #define handlers _sigfunc
  64. extern __sighandler_t _sigfunc[];
  65. #endif
  66.  
  67. #if mytramp
  68.  
  69. /* Handler for all signals that are handled by a user-specified function.
  70.    Saves and restores the general regs %g2-%g7, the %y register, and
  71.    all the FPU regs (including %fsr), around calling the user's handler.  */
  72. static void
  73. DEFUN(trampoline, (sig, code, context, addr),
  74.       int sig AND int code AND struct sigcontext *context AND PTR addr)
  75. {
  76.   int save[4];
  77.  
  78.   /* Save the call-clobbered registers.  */
  79.   asm volatile ("movem%.l d0-d1/a0-a1, %0" : : "m" (save[0]));
  80.  
  81.   /* XXX should save/restore FP regs */
  82.  
  83.   /* Call the user's handler.  */
  84.   (*((void EXFUN((*), (int sig, int code, struct sigcontext *context,
  85.                PTR addr))) handlers[sig]))
  86.     (sig, code, context, addr);
  87.  
  88.   /* Restore the call-clobbered registers.  */
  89.   asm volatile ("movem%.l %0, d0-d1/a0-a1" : : "g" (save[0]) :
  90.         "d0", "d1", "a0", "a1");
  91.  
  92.   __sigreturn (context);
  93. }
  94.  
  95. #endif
  96.  
  97. int
  98. DEFUN(__sigvec, (sig, vec, ovec),
  99.       int sig AND CONST struct sigvec *vec AND struct sigvec *ovec)
  100. {
  101. #ifndef    mytramp
  102.   extern void _sigtramp (int);
  103. #define    trampoline    _sigtramp
  104. #endif
  105.   struct sigvec myvec;
  106.   int mask;
  107.   __sighandler_t ohandler;
  108.  
  109.   if (sig <= 0 || sig >= NSIG)
  110.     {
  111.       errno = EINVAL;
  112.       return -1;
  113.     }
  114.  
  115.   mask = __sigblock(sigmask(sig));
  116.  
  117.   ohandler = handlers[sig];
  118.  
  119.   if (vec != NULL &&
  120.       vec->sv_handler != SIG_IGN && vec->sv_handler != SIG_DFL)
  121.     {
  122.       handlers[sig] = vec->sv_handler;
  123.       myvec = *vec;
  124.       myvec.sv_handler = trampoline;
  125.       vec = &myvec;
  126.     }
  127.  
  128.   if (__raw_sigvec(sig, vec, ovec) < 0)
  129.     {
  130.       int save = errno;
  131.       (void) __sigsetmask(mask);
  132.       errno = save;
  133.       return -1;
  134.     }
  135.  
  136.   if (ovec != NULL && ovec->sv_handler == trampoline)
  137.     ovec->sv_handler = ohandler;
  138.  
  139.   (void) __sigsetmask(mask);
  140.  
  141.   return 0;
  142. }
  143.